﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using HFK.DxFluentUI.HorizontalGrid.Columns;
using HFK.DxFluentUI.HorizontalGrid.ComponentModel;
using HFK.DxFluentUI.LanguageModel.HorizontalGrid;
using HFK.DxFluentUI.LanguageModel;

namespace HFK.DxFluentUI.HorizontalGrid.View
{
  public class ViewContext<ComponentType> : HorizontalGridMainViewElement<ComponentType> where ComponentType : class
  {
    #region public members

    public HorizontalGridColumnElement<ComponentType> AddColumn(string caption)
    {
      PropertyColumnContext<ComponentType> result = PropertyColumnContext<ComponentType>.Create(GridFactory, caption);
      ImplementingControl.Columns.Add(result.ImplementingControl);
      return result;
    }

    public HorizontalGridColumnElement<ComponentType> AddColumn<U>(string caption, Expression<Func<ComponentType, U>> expression)
    {
      PropertyColumnContext<ComponentType> result = PropertyColumnContext<ComponentType>.Create(GridFactory, caption);
      ImplementingControl.Columns.Add(result.ImplementingControl);

      result.BindToProperty(expression);

      return result;
    }

    public HorizontalGridDetailViewElement<ComponentType, ListedType> AddDetailView<ListedType>(string caption, Action<HorizontalGridDetailViewElement<ComponentType, ListedType>> apply) where ListedType : class
    {
      DetailViewContext<ComponentType, ListedType> viewContext = DetailViewContext<ComponentType, ListedType>.Create(GridFactory, caption, ViewLevel + 1, this);
      GridControl.ViewCollection.Add(viewContext.ImplementingControl);
      viewContext.ImplementingControl.GridControl = GridControl;

      apply(viewContext);

      return viewContext as HorizontalGridDetailViewElement<ComponentType, ListedType>;
    }

    public HorizontalGridMainViewElement<ComponentType> OptimizeColumnWidthForText()
    {
      ImplementingControl.OptionsView.ColumnAutoWidth = false;
      return this;
    }

    public HorizontalGridMainViewElement<ComponentType> OptimizeColumnWidthForView()
    {
      ImplementingControl.OptionsView.ColumnAutoWidth = true;
      return this;
    }

    public FeatureActivationElement<HorizontalGridMainViewElement<ComponentType>> WithGrouping()
    {
      return new FeatureContext<HorizontalGridMainViewElement<ComponentType>>(this.WithGroupingAllowed, this.WithGroupingNotAllowed);
    }

    public FeatureActivationElement<HorizontalGridMainViewElement<ComponentType>> WithEditing()
    {
      return new FeatureContext<HorizontalGridMainViewElement<ComponentType>>(this.WithEditingAllowed, this.WithEditingNotAllowed);
    }

    #endregion

    #region internal members

    internal static ViewContext<ComponentType> Create(HorizontalGridControlBase gridFactory, string caption, int viewLevel)
    {
      ViewContext<ComponentType> result = new ViewContext<ComponentType>(gridFactory, caption);
      result.ViewLevel = viewLevel;

      return result;
    }

    internal HorizontalGridView ImplementingControl { get { return m_control; } }
    internal HorizontalGridControl GridControl { get { return m_gridFactory.ImplementingControl; } }

    internal DevExpress.XtraGrid.GridLevelNodeCollection LevelNodeCollection { get; set; }

    internal int ViewLevel { get; set; }
    internal HorizontalGridControlBase GridFactory { get { return m_gridFactory; } }

    internal HorizontalGridMainViewElement<ComponentType> WithGroupingAllowed()
    {
      ImplementingControl.OptionsCustomization.AllowGroup = true;
      ImplementingControl.OptionsView.ShowGroupPanel = true;
      return this;
    }

    internal HorizontalGridMainViewElement<ComponentType> WithGroupingNotAllowed()
    {
      ImplementingControl.OptionsCustomization.AllowGroup = false;
      ImplementingControl.OptionsView.ShowGroupPanel = false;
      return this;
    }

    internal HorizontalGridMainViewElement<ComponentType> WithEditingAllowed()
    {
      ImplementingControl.OptionsBehavior.Editable = true;
      return this;
    }

    internal HorizontalGridMainViewElement<ComponentType> WithEditingNotAllowed()
    {
      ImplementingControl.OptionsBehavior.Editable = false;
      return this;
    }

    #endregion

    #region protected members

    protected ViewContext(HorizontalGridControlBase gridFactory,  string caption)
    {
      m_gridFactory = gridFactory;
      m_control.Name = string.Format("{0}.[{1}]", caption, System.Guid.NewGuid().ToString());
      m_control.ViewCaption = caption;
      LevelNodeCollection = GridControl.LevelTree.Nodes;
    }

    #endregion

    #region private members

    HorizontalGridView m_control = new HorizontalGridView();
    HorizontalGridControlBase m_gridFactory;

    #endregion
  }
}
